package com.ruoyi.common.utils.file;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.processing.OperationManager;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.qiniu.util.UrlSafeBase64;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @类名: QiniuUtils
 * @描述:
 * @作者: liudf
 * @日期: 2021/8/7 16:11
 */
@Component
public class QiniuUtils {

    private static final Logger log = LoggerFactory.getLogger(QiniuUtils.class);

    //设置好账号的ACCESS_KEY和SECRET_KEY
    public static String ACCESS_KEY = "w2m0fhaw8xkO9D3PwTxdSLIAx7fsUL2U40dpuE0f"; //这两个登录七牛 账号里面可以找到
    public static String SECRET_KEY = "lK6-actcL4JjzlJqFLguA10DBej8aaICOHOiXhMt";
    public static String URL = "http://lingt-file.zyh365.com/";

    //要上传的空间
    public static String BUCKET_NAME = "lingt-file"; //对应要上传到七牛上 你的那个路径（自己建文件夹 注意设置私有）

    //密钥配置
    public static Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
    //创建上传对象
    public static Configuration cfg = new Configuration(Region.region2());

    public static UploadManager uploadManager = new UploadManager(cfg);
    public static BucketManager bucketManager = new BucketManager(auth,cfg);
    public static OperationManager operationManager = new OperationManager(auth, cfg);
    public static Gson gson =  new Gson();

    /**
     * 简单上传，使用默认策略，只需要设置上传的空间名就可以了
     *
     * @param
     * @return
     */
    public String getUpToken() {
        return auth.uploadToken(BUCKET_NAME);
        //<bucket>:<key>，表示只允许用户上传指定key的文件。在这种格式下文件默认允许“修改”，已存在同名资源则会被本次覆盖。
        //如果希望只能上传指定key的文件，并且不允许修改，那么可以将下面的 insertOnly 属性值设为 1。
        //第三个参数是token的过期时间
        //return auth.uploadToken(bucketname, fileName, 3600, new StringMap().put("insertOnly", 0));
    }

    /**
     * 普通上传
     *
     * @param filePath 文件路径
     * @param fileName 文件上传至七牛云空间的名称
     * @throws IOException
     */
    public String upload(String filePath, String fileName) {
        try {
            //调用put方法上传
            if (!new File(filePath).exists()){
                System.out.println(filePath+"not exists!");
                return null;
            }
            Response response = uploadManager.put(filePath, fileName, getUpToken());
            //打印返回的信息
            System.out.println(filePath + " response:" + response.bodyString());
            DefaultPutRet putRet = gson.fromJson(response.bodyString(), DefaultPutRet.class);
            return URL + putRet.key;
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                //响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
                e.printStackTrace();
            }
        } catch (Exception e) {
            System.out.println("qiniu upload e"+e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public String uploadMultipartFile(MultipartFile file, String key) {
        //把文件转化为字节数组
        InputStream is = null;
        ByteArrayOutputStream bos = null;

        try {
            is = file.getInputStream();
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = is.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            byte[] uploadBytes = bos.toByteArray();

            String upToken = auth.uploadToken(BUCKET_NAME);
            //默认上传接口回复对象
            //进行上传操作，传入文件的字节数组，文件名，上传空间，得到回复对象
            Response response = uploadManager.put(uploadBytes, key, upToken);
            DefaultPutRet putRet = gson.fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);//key 文件名
            System.out.println(putRet.hash);//hash 七牛返回的文件存储的地址，可以使用这个地址加七牛给你提供的前缀访问到这个视频。
            return URL+putRet.key;
        } catch (QiniuException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getQiniuPath(String relaPath){
        if (StringUtils.isEmpty(relaPath)){
            return null;
        }else {
            return URL+relaPath;
        }
    }

    public static String zipFiles(List<String> fileUrlList,String zipFileName){
        String urlAndAlias = "";
        for(int i = 0 ; i < fileUrlList.size(); i++) {
            urlAndAlias += "/url/" + UrlSafeBase64.encodeToString(fileUrlList.get(i));
        }
        // srcKey不影响实际操做结果，可是根据七牛云规范，须要传入一个该资源空间实际存在的资源key。因此这里可使用已经存在的test1.txt
        String srcKey = "1.png";

        //数据处理指令，支持多个指令
        String persistentOpfs = String.format("mkzip/2%s|saveas/%s", urlAndAlias,  UrlSafeBase64.encodeToString(BUCKET_NAME + ":"+zipFileName));

        //其它参数
        StringMap options = new StringMap();
        //数据处理队列名称
//        options.put("pipeline", "pipeline");
        //数据处理完成结果通知地址
//        options.put("notifyURL", "http://121.196.57.218:8009/file/getQiniuResult");
//        options.put("force", 1);

        //构造一个带指定Zone对象的配置类
        try {
//            String persistentId = operationManager.pfop(BUCKET_NAME, srcKey, persistentOpfs,options);
            String persistentId = operationManager.pfop(BUCKET_NAME, srcKey, persistentOpfs);
            //能够根据该 persistentId 查询任务处理进度
            System.out.println("operationManager.pfop persistentId:"+persistentId);
            return persistentId;
        } catch (QiniuException e) {
            System.err.println(e.response.toString());
        }catch (Exception e) {
            System.err.println("qiniu zip pfop error:"+e.getMessage());
        }
        return null;
    }

    /**
     * 调用七牛云压缩完成后,回调接口
     * @param
     * @return
     */
/*    @RequestMapping(value = "/getQiniuResult", method = RequestMethod.POST)
    public void getQiniuResult(@RequestBody QiStatus status) {
        int code = status.code;//状态码 0：成功，1：等待处理，2：正在处理，3：处理失败，4：成功但通知失败。
        String desc = status.desc;//与状态码相对应的详细描述。
        if (code==0) {
            String id = status.id;//持久化处理的进程 ID，即前文中的<persistentId>。

            List<QiResult> items = status.getItems();
            if(items!=null && items.size()!=0){
                QiResult result =items.get(0);
                String resultCmd =result.cmd;
                int resultCode =result.code;
                String resultDesc =result.desc;
                System.out.println("################resultCmd=="+resultCmd+" resultCode=="+resultCode+" resultDesc=="+resultDesc);
                if(resultCode==0){
                    String key =result.key;
                    System.out.println("压缩包名称是="+key);
                }

            }

        }else if(code==3){
            System.out.println("处理失败,原因是:"+desc);
        }else if(code ==1 || code==2){
            System.out.println("正在处理中...");
        }else if(code==4){
            System.out.println("处理成功但通知失败");
        }
    }*/

    public static void getFileList(){
        String prefix = "";
        //每次迭代的长度限制，最大1000，推荐值 1000
        int limit = 1000;
        //指定目录分隔符，列出所有公共前缀（模拟列出目录效果）。缺省值为空字符串
        String delimiter = "";
        //列举空间文件列表
        BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(BUCKET_NAME, prefix, limit, delimiter);
        while (fileListIterator.hasNext()) {
            //处理获取的file list结果
            FileInfo[] items = fileListIterator.next();
            for (FileInfo item : items) {
                System.out.println(item.key);
                System.out.println(item.hash);
                System.out.println(item.fsize);
                System.out.println(item.mimeType);
                System.out.println(item.putTime);
                System.out.println(item.endUser);
            }
        }
    }


    /**
     * 获取下载文件路径，即：donwloadUrl
     *
     * @return
     */
    public String getDownloadUrl(String targetUrl) {
        String downloadUrl = auth.privateDownloadUrl(targetUrl);
        return downloadUrl;
    }

    public static void main(String args[]) {
        String fileName = "declaration/1628081021306-Chloride permeability of recycled aggregate con or mechanical damage.pdf";
        //上传文件的路径
        String filePath = "C:\\Users\\ldf.ARCVIDEO\\Desktop\\fsdownload\\1628081021306-Chloride permeability of recycled aggregate con or mechanical damage.pdf";  //本地要上传文件路径
//        String filePath = "C:\\Users\\ldf.ARCVIDEO\\Desktop\\fsdownload\\1628254676225-5KJYZ1ADQUBEKO4.jpg";  //本地要上传文件路径
//        new QiniuUtils().upload(filePath,fileName);
        System.out.println(getQiniuPath(fileName));

        //构造私有空间的需要生成的下载的链接；
        //格式： http://私有空间绑定的域名/空间下的文件名
        //        String targetUrl = "http://私有空间绑定的域名/下载文件名称.后缀";
        //        new QiniuUtils().download(targetUrl);

//        Configuration cfg = new Configuration(Region.region2());
//        UploadManager uploadManager = new UploadManager(cfg);
//        Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
//        String upToken = auth.uploadToken(BUCKET_NAME);
//        DefaultPutRet putRet;
       List<String> fileUrlList = new ArrayList<>(Arrays.asList("http://lingt-file.zyh365.com/declaration/1628169097530-比赛证书.pdf", "http://lingt-file.zyh365.com/declaration/1628172830578-获得专利.pdf"
       ,"http://lingt-file.zyh365.com/declaration/1628172888843-Kinetic cellulose aerogel.pdf","http://lingt-file.zyh365.com/declaration/1628163420540-Kinetic, isotherm, and thermodynamic studies of the adsorption of dye from aqueous solution by propylene glycol adipate-modified cellulose aerogel.pdf"
       ,"http://lingt-file.zyh365.com/declaration/1628163410749-Kinetic, isotherm, and thermodynamic studies of the adsorption of dye from aqueous solution by propylene glycol adipate-modified cellulose aerogel.docx"));
//

        String zipName = "declaration/zip/贾婼兰-2458.zip";
        String zipTest = zipFiles(fileUrlList, zipName);
        System.out.println(getQiniuPath(zipName));
        System.out.println("----------------------------");

//        getFileList();

       /* try {
            Response response = uploadManager.put(filePath, fileName, upToken);
            //解析上传成功的结果
            putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);//key 文件名
            System.out.println(putRet.hash);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.err.println(r.toString());
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
        String downloadUrl = auth.privateDownloadUrl("http://lingt-file.zyh365.com/test/raw.txt");
        System.out.println(downloadUrl);*/

    }

}
